
#include "CoordinateSystems.h"

bool CoordinateSystems::init()
{
	if (!LearnShader::init())	return false;
	std::cout << getChapterName().c_str() << "::" << getNodeName().c_str() << "::init" << std::endl;

	depthEnable();
	m_pProgram = createProgramWithDefaultPath();
	m_pContainer = ShaderTexture::create(Res_Image_Container);
	m_pAwesomeface = ShaderTexture::create(Res_Image_Awesomeface);

	CREATE_SHADER_VERTEX_DATA(pVertexData, Dataset_Vertices_Cube_Coord);
	pVertexData->setVertexSize(5);
	pVertexData->pushVertexAttrib(3, 0);
	pVertexData->pushVertexAttrib(2, 3);
	m_pVertex = ShaderBuffer::create( pVertexData);

	return true;
}

void CoordinateSystems::release()
{

}

static glm::vec3 cubePositions[] = {
	glm::vec3(0.0f, 0.0f, 0.0f),
	glm::vec3(2.0f, 5.0f, -15.0f),
	glm::vec3(-1.5f, -2.2f, -2.5f),
	glm::vec3(-3.8f, -2.0f, -12.3f),
	glm::vec3(2.4f, -0.4f, -3.5f),
	glm::vec3(-1.7f, 3.0f, -7.5f),
	glm::vec3(1.3f, -2.0f, -2.5f),
	glm::vec3(1.5f, 2.0f, -2.5f),
	glm::vec3(1.5f, 0.2f, -1.5f),
	glm::vec3(-1.3f, 1.0f, -1.5f)
};

void CoordinateSystems::update(float dt)
{
	glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, m_pContainer->getTexture());
	glUniform1i(glGetUniformLocation(m_pProgram->getProgram(), "ourTexture1"), 0);
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, m_pAwesomeface->getTexture());
	glUniform1i(glGetUniformLocation(m_pProgram->getProgram(), "ourTexture2"), 1);

	m_pProgram->use();

	m_pVertex->bindingVertexArray();

	glm::mat4 view;
	glm::mat4 projection;
	view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));
	projection = glm::perspective(45.0f, (GLfloat)WINDOWS_W / (GLfloat)WINDOWS_H, 0.1f, 100.0f);
	// Get their uniform location
	GLint modelLoc = glGetUniformLocation(m_pProgram->getProgram(), "model");
	GLint viewLoc = glGetUniformLocation(m_pProgram->getProgram(), "view");
	GLint projLoc = glGetUniformLocation(m_pProgram->getProgram(), "projection");
	// Pass the matrices to the shader
	glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
	// Note: currently we set the projection matrix each frame, but since the projection matrix rarely changes it's often best practice to set it outside the main loop only once.
	glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));

	for (GLuint i = 0; i < 10; i++)
	{
		// Calculate the model matrix for each object and pass it to shader before drawing
		glm::mat4 model;
		model = glm::translate(model, cubePositions[i]);
		GLfloat angle = 20.0f * i;
		model = glm::rotate(model, angle, glm::vec3(1.0f, 0.3f, 0.5f));
		glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));

		glDrawArrays(GL_TRIANGLES, 0, 36);
	}

	m_pVertex->draw(36);
	m_pVertex->cleanVertexArray();
	bindTexture(nullptr);
	swapBuffers();
}
